// 文档 https://threejs.org/docs/index.html#api/zh/cameras/CubeCamera
// 示例 https://github.com/mrdoob/three.js/blob/master/examples/webgl_shading_physical.html
import { 
  BoxGeometry,
  CubeCamera,
  CubeReflectionMapping,
  CubeRefractionMapping,
  CubeTextureLoader,
  LinearMipmapLinearFilter,
  Mesh,
  MeshStandardMaterial,
  PerspectiveCamera,
  RGBFormat,
  Scene, 
  SphereGeometry, 
  sRGBEncoding, 
  TextureLoader, 
  WebGLRenderer,
  WebGLCubeRenderTarget,
  MeshBasicMaterial,
  MultiplyOperation,
  IcosahedronBufferGeometry,
  BoxBufferGeometry,
  TorusBufferGeometry,
  TorusKnotBufferGeometry
} from "three";
import stats from '../../utils/stats';
// 调用
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GUI } from 'dat.gui';

let scene = new Scene();
let renderer = setRenderer();
let camera = setCamera();

let { sphere, cube, torus, cubeCamera1, cubeCamera2, material } = init();
// addGUI(scene);

const trackballControls = new OrbitControls(camera, renderer.domElement);
// 调整场景位置
trackballControls.target.set(0, 3, 0);

let count = 0;
function render() {
  stats.update();
  trackballControls.update();

  const time = Date.now() * 0.001;

  cube.position.x = Math.cos(time) * 30;
  cube.position.y = Math.sin(time) * 30;
  cube.position.z = Math.sin(time) * 30;
  cube.rotation.x += 0.02;
  cube.rotation.y += 0.02;

  torus.position.x = Math.cos(time + 10) * 30;
  torus.position.y = Math.sin(time + 10) * 30;
  torus.position.z = Math.sin(time + 10) * 30;

  if (count % 2 === 0) {
    cubeCamera1.update(renderer, scene);
    material.envMap = cubeCamera1.renderTarget.texture
  } else {
    cubeCamera2.update(renderer, scene);
    material.envMap = cubeCamera2.renderTarget.texture
  }
  
  count ++;

  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
render();

function setRenderer() {
  const renderer = new WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 支持阴影生成 
  renderer.shadowMap.enabled = true;
  document.body.appendChild(renderer.domElement);

  return renderer
}

function setCamera(): PerspectiveCamera {
  let camera = new PerspectiveCamera(60, window.innerWidth/window.innerHeight, 1, 1000);
  camera.position.set(0, 20, 40);
  scene.add( camera );

  return camera;
}

/** 功能区 */
function init() {
  let textureLoader = new TextureLoader();

  // 将全景图生成6张图工具
  // https://jaxry.github.io/panorama-to-cubemap/
  // https://360toolkit.co/convert-spherical-equirectangular-to-cubemap
  let urls = [
    '/textures/cubemap/flowers/right.png',
    '/textures/cubemap/flowers/left.png',
    '/textures/cubemap/flowers/top.png',
    '/textures/cubemap/flowers/bottom.png',
    '/textures/cubemap/flowers/front.png',
    '/textures/cubemap/flowers/back.png',
  ];
  let cubeLoader = new CubeTextureLoader();
  scene.background = cubeLoader.load(urls);

  let cubeRenderTarget1 = new WebGLCubeRenderTarget(256, {
    format: RGBFormat,
    generateMipmaps: true,
    minFilter: LinearMipmapLinearFilter,
    encoding: sRGBEncoding,
  } );
  let cubeCamera1 = new CubeCamera(1, 1000, cubeRenderTarget1);

  let cubeRenderTarget2 = new WebGLCubeRenderTarget(256, {
    format: RGBFormat,
    generateMipmaps: true,
    minFilter: LinearMipmapLinearFilter,
    encoding: sRGBEncoding,
  } );
  let cubeCamera2 = new CubeCamera(1, 1000, cubeRenderTarget2);

  let material = new MeshBasicMaterial({
    envMap: cubeRenderTarget2.texture,
    combine: MultiplyOperation,
    reflectivity: 1
  });

  let sphere = new Mesh(
    new IcosahedronBufferGeometry(20, 8),
    material
  );
  scene.add(sphere);

  let cube = new Mesh(
    new BoxBufferGeometry(20, 20, 20),
    material
  );
  scene.add(cube);

  let torus = new Mesh(
    new TorusKnotBufferGeometry(10, 5, 128, 16),
    material
  );
  scene.add(torus);

  return { sphere, cube, torus, cubeCamera2, cubeCamera1, material }
}


function addGUI(scene: any): void {
  const gui = new GUI();  
}